package Game;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;


public class IO {
	
	public static final int OPEN = 0;
	public static final int SAVE = 1;
	
	private IO() {};
	
	private static HashMap<String, File> languages;
	private static HashMap<String, File> graphics;
	
	static {
		languages = getJarLanguages();
		graphics = getJarGraphics();
	}
	
	public static File getGraphic(String name) {
		return graphics.get(name);
	}
	
	public static File getLanguage(String name) {
		return languages.get(name);
	}
	
	public static BufferedImage loadGraphic(File graphic) {
		try {
			return ImageIO.read(graphic);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static void addLanguage(File language) {
		languages.put(language.getName().substring(0, language.getName().length() - 5), language);
	}
	
	public static HashMap<String, String> loadFilter(File filter) {
		HashMap<String, String> strings = new HashMap<String, String>();
		try {
			BufferedReader in = new BufferedReader(new  FileReader(filter));
			String line;
			while ((line = in.readLine()) != null) {
				if (line.matches(".+[=].+")) {
					int i = line.indexOf('=');
					String key = line.substring(0, i);
					String value = line.substring(i + 1);
					strings.put(key, value);
				}
			}
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return strings;
	}
	
	public static HashMap<String, String> loadLanguage(File language) {
		addLanguage(language);
		HashMap<String, String> strings = new HashMap<String, String>();
		try {
			BufferedReader in = new BufferedReader(new  FileReader(language));
			String line;
			while ((line = in.readLine()) != null) {
				if (line.matches("[\\w]+[=].+")) {
					int i = line.indexOf('=');
					String key = line.substring(0, i);
					String value = line.substring(i + 1);
					strings.put(key, value);
				}
			}
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return strings;
	}
	
	public static HashMap<String, File> getGraphics() {
		return graphics;
	}
	
	public static HashMap<String, File> getLanguages() {
		return languages;
	}
	
	public static HashMap<String, File> getJarGraphics() {
		HashMap<String, File> graphics = new HashMap<String, File>();
		File[] files = IO.listResources("Ressources");
		for (File file : files) {
			if (file.getName().endsWith(".png")) {
				graphics.put(file.getName().substring(0, file.getName().length() - 4), file);
			}
		}
		return graphics;
	}

	public static HashMap<String, File> getJarLanguages() {
		HashMap<String, File> languages = new HashMap<String, File>();
		File[] files = IO.listResources("Ressources");
		for (File file : files) {
			if (file.getName().endsWith(".lang")) {
				languages.put(file.getName().substring(0, file.getName().length() - 5), file);
			}
		}
		return languages;
	}
	
	public static File getResource(String file) {
		try {
			return new File(URLDecoder.decode(Game.class.getResource("").getFile(), "utf-8") + file);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static File[] listResources(String dir) {
		try {
			File directory = new File(URLDecoder.decode(Game.class.getResource("").getFile(), "utf-8") + dir);
			if (directory.exists() && directory.isDirectory()) {
				return directory.listFiles();
			} else {
				ArrayList<File> files = new ArrayList<File>();
				try {
					JarFile jar = new JarFile(ClassLoader.getSystemClassLoader().getResource("Game").getFile().replaceFirst("[.]jar[!].*", ".jar").substring("file:".length()));
					Enumeration<JarEntry> entries = jar.entries();
					while (entries.hasMoreElements()) {
						JarEntry entry = entries.nextElement();
						if (entry.getName().startsWith("Game/" + dir + "/") && !entry.getName().endsWith("/") && !entry.getName().substring(("Game/" + dir + "/").length()).contains("/")) {
							String resource = entry.getName().substring("Game/".length());
							files.add(new File(Game.class.getResource(resource).getFile()));
						}
					}
					jar.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				return files.toArray(new File[files.size()]);
			}
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
			return null;
		}
	}
	
	public static File askFile(final String[] fileSufixe, int mode) {
		JFileChooser fc = new JFileChooser();
		fc.removeChoosableFileFilter(fc.getFileFilter());
		fc.setMultiSelectionEnabled(false);

		//for (int i = 0; i < fileSufixe.length; i++) {
			fc.addChoosableFileFilter(new FileNameExtensionFilter(fileSufixe[0] + "-" + Strings.getString("file"), fileSufixe));
		//}
		fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
		File result = null;
		if (mode == OPEN) {
			if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
				result = fc.getSelectedFile();
			}
		} else if (mode == SAVE) {
			if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
				result = fc.getSelectedFile();
				/*
				MyFileFilter selectedFilter = (MyFileFilter)fc.getFileFilter();
				if (result != null && !result.getName().toLowerCase().endsWith("." + selectedFilter.getAcceptedSufix())) {
					result = new File(result.toPath()+ "." + selectedFilter.getAcceptedSufix());
				}*/
			}
		}
	return result;
	}
	
	public static void saveString(String key, String value) {
		Preferences userPreferences = Preferences.userRoot().node("ultimate tic tac toe");
		userPreferences.putByteArray(key, value.getBytes());
	}
	
	public static String loadString(String key) {
		Preferences userPreferences = Preferences.userRoot().node("ultimate tic tac toe");
		byte[] bytes = userPreferences.getByteArray(key, null);
		if (bytes != null) {
			return new String(bytes);
		} else {
			return null;
		}
	}
	
	public static void clearString(String key) {
		Preferences.userRoot().node("ultimate tic tac toe").remove(key);
	}
	
	public static String[] getStrings() {
		try {
			return Preferences.userRoot().node("ultimate tic tac toe").keys();
		} catch (BackingStoreException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static void clearAllStrings() {
		try {
			Preferences.userRoot().node("ultimate tic tac toe").clear();
		} catch (BackingStoreException e) {
			e.printStackTrace();
		}
	}

}
